﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace IntoNails.Infrastructure.InteractionRequests
{
    public class InteractionDialogTriggerAction<T> : TriggerAction<Grid>
    {
        public static readonly DependencyProperty DialogProperty =
            DependencyProperty.Register("Dialog", typeof (InteractionDialogBase<T>), typeof (InteractionDialogTriggerAction<T>), new PropertyMetadata(null));

        public InteractionDialogBase<T> Dialog
        {
            get { return (InteractionDialogBase<T>) GetValue(DialogProperty); }
            set { SetValue(DialogProperty, value); }
        }

        protected override void Invoke(object parameter)
        {
            var args = parameter as RequestRaisedEventArgs<T>;
            if (args == null)
                throw new InvalidOperationException("interaction event is null");

            this.SetDialog(args.Entity, args.ObjectState, args.Callback, args.CancelCallback, null);
        }

        private void SetDialog(T entity, object state, Action<T> callback, Action cancelCallback, UIElement element)
        {
            if (!(this.Dialog is IGenericInteractionView<T>))
                return;

            IGenericInteractionView<T> view = this.Dialog as IGenericInteractionView<T>;
            view.SetEntity(entity);

            IGenericInteractionViewModel<T> viewModel = this.Dialog.DataContext as IGenericInteractionViewModel<T>;
            if (viewModel == null)
                throw new ArgumentNullException("viewModel");

            viewModel.ViewInvoked(state);

            EventHandler handler = null;
            handler = (s, e) =>
                          {
                              this.Dialog.DialogSubmit -= handler;
                              this.Dialog.DialogCancel -= handler;
                              this.AssociatedObject.Children.Remove(this.Dialog);

                              if (e.ToString() == InteractionDialogResult.Submit.ToString())
                                  callback(view.GetEntity());
                              else
                                  cancelCallback();
                          };
                
            this.Dialog.DialogSubmit += handler;
            this.Dialog.DialogCancel += handler;
            this.Dialog.SetValue(Grid.RowSpanProperty, this.AssociatedObject.RowDefinitions.Count == 0 ? 1 : this.AssociatedObject.RowDefinitions.Count);
            this.Dialog.SetValue(Grid.ColumnSpanProperty, this.AssociatedObject.ColumnDefinitions.Count == 0 ? 1 : this.AssociatedObject.ColumnDefinitions.Count);
            this.AssociatedObject.Children.Add(this.Dialog);
        }
    }
}
